package progetto;

import peersim.config.Configuration;
import peersim.core.Control;
import peersim.core.Network;
import peersim.core.Node;

/**
 * This initialization class collects the simulation parameters from the config
 * file and generates uniformly random 2D-coordinates for each node. The
 * coordinates are distributed on a unit (1.0) square.
 * 
 * 
 * 
 * @author Catia Prandi
 */
public class NodeStatusInitializer implements Control {

	// ------------------------------------------------------------------------
	// Parameters
	// ------------------------------------------------------------------------
	/**
     * The protocol to operate on.
     * 
     * @config
     */
	private static final String PAR_STATUS_PROT = "protocol";
	
	/**
	 * Percentage of OS targeted by the virus
	 * Default value: 30
	 * 
	 * @config
	 */
	private static final String PAR_SO = "so_infec";
	
	
	private static final String PAR_FIXED = "fixed_percent";
	
	
	private static final int DEFAULT_SO_INFECTED = 30;
	
	private static final double DEFAULT_FIXED = 35;
	

	
	// ------------------------------------------------------------------------
	// Fields
	// ------------------------------------------------------------------------
	/** Protocol identifier.
	 * Obtained from config property
     * {@link #PAR_STATUS_PROT}.
	 * */
	
	private final double fixedPercent;
	private final int statusPid;
	
	/**
	 * Percentage of nodes with the OS targeted by the virus
	 * Obtained from config property
     * {@link #PAR_STATUS_PROT}.
	 */
	private final double soInfected;

	
	
	
	// ------------------------------------------------------------------------
	// Constructor
	// ------------------------------------------------------------------------
	public NodeStatusInitializer(String prefix) {
	     statusPid = Configuration.getPid(prefix + "." + PAR_STATUS_PROT);
	     fixedPercent = Configuration.getDouble(prefix + "." + PAR_FIXED, DEFAULT_FIXED);
	     //System.out.println("fixedPercent "+fixedPercent);
	     double tmpSOInfected = Configuration.getDouble(prefix + "." + PAR_SO, DEFAULT_SO_INFECTED);
	    
	     if(tmpSOInfected > 100 || tmpSOInfected < 1 ) {

	    	 soInfected = DEFAULT_SO_INFECTED;
	    	 System.err.println("Percentage of SO targeted by the virus not valid, used the default value: "+DEFAULT_SO_INFECTED+"%");
	     } else 
	    	 soInfected = tmpSOInfected;
	     
	     
	}
	
	/**
     * Initialize the node coordinates. The first node in the {@link Network} is
     * the root node by default and it is located in the middle (the center of
     * the square) of the surface area.
     */
	@Override
    public boolean execute() {
		//System.out.print(Network.size()/100);
		int fixed = (int)(Network.size() * fixedPercent / 100);
		System.out.println("numero di nodi fissi "+ fixed);
		for(int i=0; i<fixed; i++) {
			Node node = Network.get(i);
			NodeStatus ns = (NodeStatus)node.getProtocol(statusPid);
			ns.setFixed(true);
		}
		
		Network.shuffle();
		
		//the infection starts with a randomly chosen node
		Node n = Network.get(0);
		NodeStatus prot = (NodeStatus) n.getProtocol(statusPid);
		prot.setInfected(true);
		
		int numberSOInfected = getNumSOInfected();
		
		//this line is used only for speed up the execution of experiments
		Network.setCapacity(numberSOInfected);
		
		//set "numberSOInfected" nodes with the infected SO 
        for (int i = 0; i < numberSOInfected; i++) {
            n = Network.get(i);
            prot = (NodeStatus) n.getProtocol(statusPid);
            prot.setInfectedSO(true);
          
         
        }
       
        //System.out.println("nuova dimensione della rete "+Network.size());
        
        return false;
    }
	
	
	/**
	 * 
	 * @return the integer number of nodes with the OS of the node infected
	 */
	private int getNumSOInfected() {
		return (int)(Network.size() * soInfected / 100);
	}

	


}
